package com.vpclub.controller;

import com.vpclub.service.DeferredResultQueue;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

import java.util.UUID;
import java.util.concurrent.Callable;

/**
 * @author : leimingchao
 * @date Date : 2021年07月06日 19:45
 */
@Controller
public class AsyncController {


    /**
     * 1.控制器返回Callable
     * 2.Spring异步处理，将Callable提交到TaskExecutor使用一个隔离的线程进行执行
     * 3.DispatcherServlet和所有的Filter退出web容器的线程，但是response保持打开状态
     * 4.Callable返回结果，SpringMVC将请求重新派发给容器，恢复之前的处理
     * 5.根据Callable返回的结果，SpringMVC继续进行视图渲染流程等(从收请求-视图渲染)
     *
     *       preHandle.........../async01
     *      主线程开始。。。Thread[http-nio-8080-exec-5,5,main]====>1625572530486
     *      主线程结束。。。Thread[http-nio-8080-exec-5,5,main]====>1625572530486
     *      ===========DispatcherServlet和所有的Filter退出线程===================================
     *
     *      ===============================等待Callable执行=============================================
     *      副线程开始。。。Thread[MvcAsync1,5,main]====>1625572530490
     *      副线程结束。。。Thread[MvcAsync1,5,main]====>1625572532499
     *      ===============================Callable执行完成=============================================
     *
     *
     *      ===============================Callable执行完成=============================================
     *      preHandle.........../async01
     *      postHandle...........(Callable之前的返回值就是目标方法的返回值)
     *      afterCompletion...........
     *
     *
     *      异步拦截器：
     *          1.原生API的AsyncListener
     *          2.SpringMVC:实现AsyncHandlerInterceptor
     *
     *
     * @return
     */
    @RequestMapping(value = "/async01")
    @ResponseBody
    public Callable<String> async01() {
        System.out.println("主线程开始。。。" + Thread.currentThread() + "====>" +System.currentTimeMillis());
        Callable<String> callable = () ->{
            System.out.println("副线程开始。。。" + Thread.currentThread() + "====>" +System.currentTimeMillis());
            Thread.sleep(2000);
            System.out.println("副线程结束。。。" + Thread.currentThread() + "====>" +System.currentTimeMillis());
            return "Callable<String> async01()";
        };
        System.out.println("主线程结束。。。" + Thread.currentThread() + "====>" +System.currentTimeMillis());
        return callable;
    }

    @RequestMapping(value = "/createOrder")
    @ResponseBody
    public DeferredResult<Object> createOrder() {
        DeferredResult<Object> deferredResult = new DeferredResult<>((long)3000,"create fail");
        DeferredResultQueue.save(deferredResult);
        return deferredResult;
    }

    @RequestMapping(value = "/create")
    @ResponseBody
    public String create() {
        //创建订单
        String order = UUID.randomUUID().toString();
        DeferredResult<Object> deferredResult = DeferredResultQueue.get();
        deferredResult.setResult(order);
        return "success====>" +order;
    }
}
